package com.syf.feign;

import com.syf.config.feign.OAuth2FeignConfig;
import com.syf.dto.UserDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
import java.util.Map;

/**
 * 1.@FeignClient注解的常用参数:
 *      name：指定FeignClient的名称，如果项目使用了Ribbon，name属性会作为微服务的名称，用于服务发现
 *      url: url一般用于调试，可以手动指定@FeignClient调用的地址
 *      path: 定义当前FeignClient的统一前缀【访问方法url的前缀： /users/basic/users】
 *      configuration: 使自定义的Feign配置类生效，可以自定义Feign的Encoder、Decoder、LogLevel、Contract
 *      fallback: 定义容错的处理类，当调用远程接口失败或超时时，会调用对应接口的容错逻辑，fallback指定的类必须实现@FeignClient标记的接口
 *      decode404:当发生http 404错误时，如果该字段位true，会调用decoder进行解码，否则抛出FeignException
 *      fallbackFactory: 工厂类，用于生成fallback类示例，通过这个属性我们可以实现每个接口通用的容错逻辑，减少重复的代码
 *
 * 2.OAuth2FeignConfig是feign的拦截器，实现了RequestInterceptor接口:
 *      将该token传递给feign将要发起的请求
 *
 * 3.远程调用流程：
 *      admin模块导入member-api模块， 那边调用该接口方法getBasicUsers()【其中有token传递（不再是去请求一个新的token）】
 *      此接口UserServiceFeign 被 UserController控制层实现，去执行该方法的实现（查询操作）
 *
 */
@FeignClient(name = "member-service",configuration = OAuth2FeignConfig.class ,path = "/users")
public interface UserServiceFeign {

    /**
     * 1. 用于其他模块 远程调用member-service中的方法
     *  1)参数：
     *      List<Long>    用户Id（集合）
     *      用户名
     *      电话号码
     *  2)返回值：
     *      Map<Long,UserDto> Long:用户ID userId,   UserDto 用户的基础信息
     *
     *  3)原本的方法（改进了）：
     *      List<UserDto>  getBasicUsers(@RequestParam("ids") List<Long> ids) ;
     */
    @GetMapping("/basic/users")
    Map<Long, UserDto> getBasicUsers ( //
            @RequestParam(value = "ids", required = false) List<Long> ids,  //参数名, 非必须(可以不传这个参数)
            @RequestParam(value = "userName", required = false) String userName,
            @RequestParam(value = "mobile", required = false) String mobile
    ) ;






    /**
     * 容错处理类，当调用失败时，简单返回空字符串,配合fallback使用
     * 需要使用@Component注解，保证fallback类被Spring容器扫描到
     *
     * fallback = UserServiceFeign.DefaultFallback.class   //fallback指定的类必须实现@FeignClient标记的接口(UserServiceFeign)
     */
    /*@Component
    public class DefaultFallback implements  UserServiceFeign{
        public String searchRepo(@RequestParam("q") String queryStr) {
            return "";
        }
    }*/
}
